package view;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;
import javax.swing.JPanel;

import model.GameState;
import model.input.KeyboardHandler;
import model.input.MouseHandler;
import view.images.SpriteCache;
import view.sounds.SoundCache;
import view.stages.AbstractStage;

public class GameUI extends Canvas implements Screen{

	private static final long serialVersionUID = 1L;

	public BufferStrategy strategy;
	private JFrame window;
	private AbstractStage stage;
	private GameState gameState;
	private SpriteCache spriteCache;
	private SoundCache soundCache;
	
	MouseHandler mouseHandler;
	KeyboardHandler keyboardHandler;

	public GameUI() {

		spriteCache = new SpriteCache();
		soundCache = new SoundCache();
		buildFrame();

	}

	public void paint() {
		Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
		g.setColor(Color.black);
		g.fillRect(0, 0, Screen.WIDTH, Screen.HEIGHT);
		stage.paint(g);
		setIgnoreRepaint(true);
		strategy.show();
		

	}
	public void update() {
		stage.update();
	}

	private void buildFrame() {
		window = new JFrame("Nocturne");
		window.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		JPanel panel = (JPanel) window.getContentPane();
		setBounds(0,0,Screen.WIDTH, Screen.HEIGHT);
		panel.setPreferredSize(new Dimension(Screen.WIDTH, Screen.HEIGHT));
		panel.setLayout(null);
		panel.add(this);

		window.setBounds(0, 0, Screen.WIDTH, Screen.HEIGHT);
		//window.setSize(Screen.WIDTH, Screen.HEIGHT);
		window.setLocationRelativeTo(null);
		window.setVisible(true);

		addMouseMotionListener(new MouseMotionAdapter() {

			@Override
			public void mouseMoved(MouseEvent evt) {
				try {
					mouseHandler.mouseMoved(evt);
				} catch (Exception e) {
					//System.err.println("mouseMoved error!");
				}
			}
		});

		addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent evt) {
				mouseHandler.mouseCliked(evt);
			}
		});

		addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {
				if(keyboardHandler != null)
					keyboardHandler.keyTyped(e);

			}

			@Override
			public void keyReleased(KeyEvent e) {
				if(keyboardHandler != null)
					keyboardHandler.keyReleased(e);

			}

			@Override
			public void keyPressed(KeyEvent e) {
				if(keyboardHandler != null)
					keyboardHandler.keyPressed(e);

			}
		});

		window.setResizable(true);
		createBufferStrategy(2);
		strategy = getBufferStrategy();
		requestFocus();
	}

	public void setStage(AbstractStage stage) {
		this.stage = stage;
	}

	public SpriteCache getSpriteCache() {
		return spriteCache;
	}

	public SoundCache getSoundCache() {
		return soundCache;
	}

	public GameState getGameState() {
		return gameState;
	}

	public void setGameState(GameState gameState) {
		this.gameState = gameState;
	}

	public MouseHandler getMouseHandler() {
		return mouseHandler;
	}

	public void setMouseHandler(MouseHandler mouseHandler) {
		this.mouseHandler = mouseHandler;
	}

	public void setKeyboardHandler(KeyboardHandler keyboardHandler) {
		this.keyboardHandler = keyboardHandler;
	}

}
